package com.unionftech.content_login.model

import android.text.TextUtils
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import com.unionftech.baselibrary.base.BaseApplication
import com.unionftech.common.base.mvp.impl.IBaseCallBack
import com.unionftech.common.bean.ResponseResult
import com.unionftech.common.network.SimpleNetWork
import com.unionftech.common.utils.LogUtils
import com.unionftech.common.utils.Utils
import com.unionftech.content_login.bean.LoginLockWarning
import com.unionftech.content_login.bean.LoginTokenInfo
import com.unionftech.content_login.bean.request.ForgetPasswordRequest
import com.unionftech.content_login.contract.LoginContract
import com.unionftech.content_login.manager.ApiManager
import com.unionftech.content_login.service.LoginConstants
import com.unionftech.content_login.util.TokenManager
import okhttp3.RequestBody.Companion.toRequestBody

class LoginModel : BaseParentModel(), LoginContract.ILoginModel {
    private val gson by lazy { Gson() }

    companion object {
        /**
         * 邮箱、密码登录的account和password
         */
        private const val ACCOUNT_STR = "account"
        private const val PASSWORD_STR = "password"

        /**
         * 网易一键登录的accessToken和token
         */
        private const val ACCESS_TOKEN = "accessToken"
        private const val TOKEN = "token"
        private const val TYPE = "type"
    }

    override fun login(
        account: String,
        password: String,
        callBack: IBaseCallBack<ResponseResult<Any?>>?,
    ) {
        execute {
            val result = request {
                val uuid = Utils.generateUniqueId(BaseApplication.appContext)
                val model = Utils.getPrettyDeviceName()
                val version = "V" + Utils.getVersionName(BaseApplication.appContext)
                val jsonObject = JsonObject()
                jsonObject.addProperty(ACCOUNT_STR, account)
                jsonObject.addProperty(PASSWORD_STR, password)
                val body = gson.toJson(jsonObject).toRequestBody(SimpleNetWork.JSON)
                val responseString =
                    ApiManager.getInstance().apiLogin().login(uuid, model, version, body)
                return@request transResponseToLoginInfo(responseString)
            }
            //存储登录token
            result.data?.let {
                if (result.code == ResponseResult.SUCCESS_CODE
                    || result.code == LoginConstants.Code.REMOTE_LOGIN_WARNING
                ) {
                    LogUtils.d("LoginModel", "loginTokenInfo--->$it")
                    TokenManager.getInstance().saveToken(it as LoginTokenInfo)
                }
            }
            callBack?.onResponse(result)
        }
    }

    override fun thirdlogin(
        token: String,
        accessToken: String,
        type: Int,
        callBack: IBaseCallBack<ResponseResult<Any?>>?
    ) {
        execute {
            val result = request {
                val uuid = Utils.generateUniqueId(BaseApplication.appContext)
                val model = Utils.getPrettyDeviceName()
                val version = "V" + Utils.getVersionName(BaseApplication.appContext)
                val jsonObject = JsonObject()
                if (!TextUtils.isEmpty(accessToken)) {
                    jsonObject.addProperty(ACCESS_TOKEN, accessToken)
                }
                if (!TextUtils.isEmpty(token)) {
                    jsonObject.addProperty(TOKEN, token)
                }
                jsonObject.addProperty(TYPE, type)
                val body = gson.toJson(jsonObject).toRequestBody(SimpleNetWork.JSON)
                val responseString =
                    ApiManager.getInstance().apiLogin().thirdlogin(uuid, model, version, body)
                return@request transResponseToLoginInfo(responseString)
            }
            //存储登录token
            result.data?.let {
                if (result.code == ResponseResult.SUCCESS_CODE
                    || result.code == LoginConstants.Code.REGISTER_LOGIN_SUCCESS
                    || result.code == LoginConstants.Code.REMOTE_LOGIN_WARNING
                ) {
                    TokenManager.getInstance().saveToken(it as LoginTokenInfo)
                }
            }
            callBack?.onResponse(result)
        }
    }

    private fun transResponseToLoginInfo(responseString: String): ResponseResult<Any?> {
        val element = JsonParser.parseString(responseString)
        val resJsonObject = element.asJsonObject
        val code = resJsonObject.get("code").asString
        if (code == LoginConstants.Code.LOGIN_LOCK_WARNING) {
            val responseResult = gson.fromJson<ResponseResult<LoginLockWarning>>(
                element,
                object : TypeToken<ResponseResult<LoginLockWarning>>() {}.type
            )
            return responseResult as ResponseResult<Any?>
        } else {
            val responseResult = gson.fromJson<ResponseResult<LoginTokenInfo>>(
                element,
                object : TypeToken<ResponseResult<LoginTokenInfo>>() {}.type
            )
            return responseResult as ResponseResult<Any?>
        }
    }

    override fun logout(callBack: IBaseCallBack<ResponseResult<Any?>>) {
        execute {
            val token = TokenManager.getInstance().getAccessToken()
            val result = request {
                ApiManager.getInstance().apiLogin().logout(token)
            }
            callBack.onResponse(result)
        }
    }

    override fun resetPassword(
        request: ForgetPasswordRequest, callBack: IBaseCallBack<ResponseResult<Any?>>
    ) {
        execute {
            val result = request {
                val body = gson.toJson(request, ForgetPasswordRequest::class.java)
                    .toRequestBody(SimpleNetWork.JSON)
                ApiManager.getInstance().apiLogin().resetPassword(body)
            }
            callBack.onResponse(result)
        }
    }
}